home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / TTidyApplication w⁄Summa Folder / TTidyApplication w⁄Summary / For MacApp 3.1 / UTidyApplication.cp next >
Encoding:
Text File  |  1994-02-26  |  7.5 KB  |  280 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        UTidyApplication.cp
  3.  
  4.     Contains:    TTidyApplication::Free() and functions and member functions
  5.                 which it calls. For use with MacApp 3.1.
  6.  
  7.     Written by:    Adam Wildavsky
  8.  
  9.     Copyright:    © 1994 by Adam Wildavsky
  10.  
  11.     Change History (most recent first):
  12.  
  13.                  2/26/94    aw        Added a To Do item. Added a comment. No code changes.
  14.                  2/24/94    aw        Trimmed blanks, added punctuation. No code changes.
  15.                  2/3/94        aw        Updated for MacApp 3.1b1
  16.                  1/23/94    aw        Baseline
  17.  
  18.     To Do:
  19.         Free ClassDesc::fgClassDescListByID and ClassDesc::fgClassDescListByName.
  20.         Clean up non-object allocations.
  21. */
  22.  
  23.  
  24. #ifndef __UTIDYAPPLICATION__
  25. #include "UTidyApplication.h"
  26. #endif
  27.  
  28. #ifndef __MACAPP__
  29. #include <MacApp.h>
  30. #endif
  31.  
  32.  
  33. #pragma segment AClose
  34. static void DeInitUMenuMgr()
  35. {
  36.     /*******
  37.  
  38.     Clean up the objects allocated by InitUMenuMgr, in reverse order of allocation.
  39.  
  40.     ********/
  41.  
  42.     extern TObject * gMenuTable;    //    Actually these are all TObject descendants,
  43.     extern TObject * gCmdTable;        //    but this will work! If we had declared them
  44.     extern TObject * gMenuIDList;    //    as their actual types we'd have cast them
  45.                                     //    to TObjects anyway for FreeIfObject().
  46.  
  47.     gMenuTable    = FreeIfObject(gMenuTable);
  48.     gCmdTable    = FreeIfObject(gCmdTable);
  49.     gMenuIDList    = FreeIfObject(gMenuIDList);
  50. }
  51.  
  52.  
  53. #pragma segment AClose
  54. static void DeInitUClassDesc()
  55. {
  56.     /*******
  57.  
  58.     An abortive attempt to clean up the objects allocated by
  59.     ClassDesc::InitUClassDesc.
  60.  
  61.     In fact the static members fgClassDescListByID and fgClassDescListByName are
  62.     private; we can't access them from here without modifying MacApp. If one were
  63.     to modify MacApp one would probably make this a ClassDesc static method.
  64.  
  65.     As it turns out leaving them around is not much of a hindrance to us since
  66.     Steve Jasik's "The Debugger" doesn't list them in its "Objects by  …" displays.
  67.  
  68.     ********/
  69.  
  70. #if FALSE
  71.     ClassDesc::fgClassDescListByID     =
  72.         (TClassDescListByID *)   FreeIfObject(ClassDesc::fgClassDescListByID);
  73.     ClassDesc::fgClassDescListByName =
  74.         (TClassDescListByName *) FreeIfObject(ClassDesc::fgClassDescListByName);
  75. #endif
  76. }
  77.  
  78.  
  79. #pragma segment AClose
  80. static void DeInitUObject()
  81. {
  82.     /*******
  83.  
  84.     Clean up anything allocated allocated by InitUObject.
  85.     This function exists solely to make the structure
  86.     easier to understand and maintain. Each InitU… function
  87.     which causes TObject allocations has a corresponding
  88.     DeInitU… function, and they are called in reverse order
  89.     of one another.
  90.  
  91.     ********/
  92.  
  93.     DeInitUClassDesc();
  94. }
  95.  
  96.  
  97. #pragma segment AClose
  98. static void DeInitUDialog()
  99. {
  100.     /*******
  101.  
  102.     Clean up the objects allocated by InitUDialog, in reverse order of allocation.
  103.  
  104.     ********/
  105.  
  106.     //    This test is necessary because gFloatingTEManager and gParamTxt
  107.     //    are -not- initialized to NULL when they are defined in UDialog.cp
  108.     if (gUDialogInitialized)
  109.     {
  110.         gFloatingTEManager    = (TFloatingTEManager *)    FreeIfObject(gFloatingTEManager);
  111.  
  112.         extern TAssociation * gParamTxt;    //    It should be empty now
  113.         gParamTxt            = (TAssociation *)            FreeIfObject(gParamTxt);
  114.     }
  115. }
  116.  
  117.  
  118. #pragma segment AClose
  119. static void DeInitUAdorners()
  120. {
  121.     /*******
  122.  
  123.     Clean up the objects allocated by InitUAdorners, in reverse order of allocation.
  124.     They're only in reverse order for form's sake!
  125.  
  126.     This function wasn't necessary in MacApp 3.0.1 as the adorners were freed when
  127.     "gGlobalContext" was freed. In MacApp 3.1 gGlobalContext no longer exists!
  128.  
  129.     ********/
  130.  
  131.     gSelectionAdorner    = (TSelectionAdorner *)        FreeIfObject(gSelectionAdorner);
  132.     gResizeIconAdorner    = (TResizeIconAdorner *)    FreeIfObject(gResizeIconAdorner);
  133.     gPrintAdorner        = (TPrintAdorner *)            FreeIfObject(gPrintAdorner);
  134.     gHiliteAdorner        = (THiliteAdorner *)        FreeIfObject(gHiliteAdorner);
  135.     gEraseAdorner        = (TEraseAdorner *)            FreeIfObject(gEraseAdorner);
  136.     gDrawAdorner        = (TDrawAdorner *)            FreeIfObject(gDrawAdorner);
  137.     gDimAdorner            = (TDimAdorner *)            FreeIfObject(gDimAdorner);
  138. }
  139.  
  140.  
  141. #pragma segment AClose
  142. static void DeInitUMacApp()
  143. {
  144.     /*******
  145.  
  146.     Clean up the objects allocated by InitUMacApp, in reverse order of allocation.
  147.  
  148.     ********/
  149.  
  150.     DeInitUDialog();
  151.     DeInitUMenuMgr();
  152.     DeInitUAdorners();
  153.  
  154.     extern TDynamicArray * gSignatures;
  155.     gSignatures            = (TDynamicArray *) FreeIfObject(gSignatures);
  156.  
  157.     //    This test wasn't necessary in MacApp 3.0. It is now because
  158.     //    we're dealing with pointers. Setting one pointer to NULL won't
  159.     //    set the other to NULL even if they were pointing to the same thing!
  160.     if (gPrintHandler == gNullPrintHandler)
  161.     {
  162.         gPrintHandler        = (TPrintHandler *)    FreeIfObject(gPrintHandler);
  163.         gNullPrintHandler    = NULL;
  164.     }
  165.     else
  166.     {
  167.         gPrintHandler        = (TPrintHandler *)    FreeIfObject(gPrintHandler);
  168.         gNullPrintHandler    = (TPrintHandler *) FreeIfObject(gNullPrintHandler);
  169.     }
  170.  
  171.     DeInitUObject();
  172. }
  173.  
  174.  
  175. #pragma segment AClose
  176. static void LastChance()
  177. {
  178.     //    Set a breakpoint here in order to check for memory leaks.
  179.     //    In Jasik do an "Objects by Time".
  180.  
  181. #if qDebug
  182.     ProgramBreak("It's time to check for memory leaks!");
  183. #endif
  184. }
  185.  
  186.  
  187. #pragma segment AClose
  188. void TTidyApplication::CleanUpAfterIApplication()
  189. {
  190.     /*******
  191.  
  192.     Clean up the objects allocated by TApplication::IApplication, in reverse order of allocation.
  193.  
  194.     ********/
  195.  
  196.     gMenuBarManager        = (TMenuBarManager *)    FreeIfObject(gMenuBarManager);
  197.     gMacAppDependencies    = (TDependencySpace *)    FreeIfObject(gMacAppDependencies);
  198.  
  199.     fPendingReplyList    = (TEventList *)        FreeListIfObject(fPendingReplyList);
  200.  
  201.     //    This rigamarole is necessary because TEvent::Free() checks to see whether
  202.     //    the event is still on the event list.
  203.     if (fEventList != NULL)
  204.     {
  205.         TEvent * anEvent;
  206.  
  207.         while ((anEvent = (TEvent *) fEventList->Last()) != NULL)
  208.         {
  209.             fEventList->AtDelete(fEventList->GetSize());
  210.             anEvent->Free();
  211.         }
  212.  
  213.         fEventList->Free();
  214.     }
  215.  
  216.     fDocumentList        = (TList *)                FreeListIfObject(fDocumentList);
  217.  
  218.     //    Must do this -before- freeing fFreeWindowList
  219.     TView * theDeskScrapView = gClipboardMgr->fClipOrphanage;
  220.     if (theDeskScrapView != NULL)
  221.     {
  222.         //    Because TDeskScrapView overrides Free to -not- call inherited::Free
  223.         theDeskScrapView->TView::Free();
  224.  
  225.         if (gClipboardMgr->fClipView == theDeskScrapView)
  226.             gClipboardMgr->fClipView = NULL;
  227.         gClipboardMgr->fClipOrphanage = NULL;
  228.     }
  229.  
  230.     fFreeWindowList        = (TList *)                FreeListIfObject(fFreeWindowList);
  231. }
  232.  
  233.  
  234. #pragma segment AClose
  235. void TTidyApplication::CleanUpJustInTimeObjects()
  236. {
  237.     //    gWindows is created on a "just in time" basis by RegisterWindow() in UWindows.cp.
  238.     //    It seems to be the only object that MacApp creates in this fashion.
  239.  
  240.     extern TDynamicArray * gWindows;
  241.     gWindows = (TDynamicArray *) FreeIfObject(gWindows);
  242. }
  243.  
  244.  
  245. #pragma segment AClose
  246. void TTidyApplication::Free() // Override
  247. {
  248.     /******
  249.  
  250.     Some of the objects which MacApp 3.0.1 allocates are freed by TApplication::Close(),
  251.     which is called from TQuitCommand::DoIt(). Some others are freed when CleanUpMacApp()
  252.     calls gApplication->Free(), resulting in calls to TCommandHandler::Free() and
  253.     TEventHandler::Free(). Others are not freed at all; they disappear when the
  254.     application's heap is disposed of after the application terminates.
  255.  
  256.     This set of functions endeavors to clean up what MacApp doesn't. One reason to
  257.     do so is that one can set a breakpoint just before the application terminates
  258.     and learn from the results. Any objects left are objects one's own application
  259.     has allocated but not freed. Some of these may span the life of the application
  260.     and need not be freed except to make the rest stand out (as above); others
  261.     represent likely memory leaks.
  262.  
  263.     *******/
  264.  
  265. #ifdef qCleanUpAtQuit
  266.     this->CleanUpAfterIApplication();
  267.     this->CleanUpJustInTimeObjects();
  268.  
  269.     DeInitUMacApp();
  270. #endif
  271.  
  272.     this->TApplication::Free();
  273.  
  274.     //    Be sure not to refer to members of gApplication
  275.     //    after calling TApplication::Free()!
  276.  
  277. #ifdef qCleanUpAtQuit
  278.     LastChance();
  279. #endif
  280. }